#include "CTriangleMesh.h"

CTriangleMesh::CTriangleMesh()
{

}


CTriangleMesh::~CTriangleMesh()
{

}


boolean	CTriangleMesh::Sweep( const CVector3d& pos, fixed radius, const CVector3d& v1, const CVector3d& v2, fixed &t, int &faceIdx ) const
{
	boolean retVal = FALSE;

	fixed minimumT = CMathFixed_FloatToFixed( 100.0f ); // init
	CVector3d relPos = GetVertex(0) - pos;
	CVector3d relVel = v2 - v1;

	if ( relPos * relVel  < 0 ) // objects moving away from each other
	{
		t = 0;
		return Intersects( pos, radius, faceIdx );
	}

	for ( int i = 0; i < GetNumFaces(); ++i )
	{
		const CVector3d* tv0 = &GetFaceVertex( i, 0 );
		const CVector3d* tv1 = &GetFaceVertex( i, 1 );
		const CVector3d* tv2 = &GetFaceVertex( i, 2 );

		if ( CTriangle3d::Sweep( *tv0, *tv1, *tv2, pos, radius, v1, v2, t ) )
		{
			retVal = TRUE;
			if ( minimumT < t )
			{
				minimumT = t;
				faceIdx = i;
				if ( t == 0 )
					return retVal;
			}
		}
	}

	return retVal;
}


boolean	CTriangleMesh::Sweep( const CVector3d& segA, const CVector3d& segB, fixed radius, const CVector3d& v1, const CVector3d& v2, fixed &t, int &faceIdx ) const
{
	boolean retVal = FALSE;
	fixed minimumT = CMathFixed_FloatToFixed( 100.0f ); // init
	CVector3d relPos = GetVertex(0) - segA;
	CVector3d relVel = v2 - v1;

	if ( relPos * relVel  < 0 ) // objects moving away from each other
	{
		t = 0;
		return Intersects( segA, segB, radius, faceIdx );
	}


	for ( int i = 0; i < GetNumFaces(); ++i )
	{
		const CVector3d* tv0 = &GetFaceVertex( i, 0 );
		const CVector3d* tv1 = &GetFaceVertex( i, 1 );
		const CVector3d* tv2 = &GetFaceVertex( i, 2 );

		if ( CTriangle3d::Sweep( *tv0, *tv1, *tv2, segA, segB, radius, v1, v2, t ) )
		{
			retVal = TRUE;
			if ( minimumT < t )
			{
				minimumT = t;
				faceIdx = i;
				if ( t == 0 )
					return retVal;
			}
		}
	}

	return retVal;
}
	

boolean CTriangleMesh::Intersects( const CVector3d& pos, const fixed radius, int &faceIdx ) const
{
	boolean retVal = FALSE;
	//fixed minimumT = CMathFixed_FloatToFixed( 100.0f ); // init

	for ( int i = 0; i < GetNumFaces(); ++i )
	{
		const CVector3d* tv0 = &GetFaceVertex( i, 0 );
		const CVector3d* tv1 = &GetFaceVertex( i, 1 );
		const CVector3d* tv2 = &GetFaceVertex( i, 2 );

		if ( CTriangle3d::Intersects( *tv0, *tv1, *tv2, pos, radius ) )
		{
			faceIdx = i;
			return TRUE;
		}
	}

	return retVal;
}


boolean	CTriangleMesh::Intersects( const CVector3d& segA, const CVector3d& segB, fixed radius, int &faceIdx ) const
{
	boolean retVal = FALSE;
	//fixed minimumT = CMathFixed_FloatToFixed( 100.0f ); // init

	for ( int i = 0; i < GetNumFaces(); ++i )
	{
		const CVector3d* tv0 = &GetFaceVertex( i, 0 );
		const CVector3d* tv1 = &GetFaceVertex( i, 1 );
		const CVector3d* tv2 = &GetFaceVertex( i, 2 );

		if ( CTriangle3d::Intersects( *tv0, *tv1, *tv2, segA, segB, radius ) )
		{
			faceIdx = i;
			return TRUE;
		}
	}

	return retVal;
}


boolean	CTriangleMesh::Intersects( const CVector3d& tv0, const CVector3d& tv1, const CVector3d& tv2, int &faceIdx ) const
{
	boolean retVal = FALSE;
	//fixed minimumT = CMathFixed_FloatToFixed( 100.0f ); // init

	for ( int i = 0; i < GetNumFaces(); ++i )
	{
		const CVector3d* t0v0 = &GetFaceVertex( i, 0 );
		const CVector3d* t0v1 = &GetFaceVertex( i, 1 );
		const CVector3d* t0v2 = &GetFaceVertex( i, 2 );

		if ( CTriangle3d::Intersects( *t0v0, *t0v1, *t0v2, tv0, tv1, tv2 ) )
		{
			faceIdx = i;
			return TRUE;
		}
	}

	return retVal;
}


boolean	CTriangleMesh::Intersects( const CPlane& plane, int &faceIdx ) const
{
	boolean retVal = FALSE;
	//fixed minimumT = CMathFixed_FloatToFixed( 100.0f ); // init

	for ( int i = 0; i < GetNumFaces(); ++i )
	{
		const CVector3d* tv0 = &GetFaceVertex( i, 0 );
		const CVector3d* tv1 = &GetFaceVertex( i, 1 );
		const CVector3d* tv2 = &GetFaceVertex( i, 2 );

		if ( CTriangle3d::Intersects( *tv0, *tv1, *tv2, plane ) )
		{
			faceIdx = i;
			return TRUE;
		}
	}

	return retVal;
}


boolean	CTriangleMesh::IsMeshConvex() const
{
	return FALSE;
}